﻿//#include <iostream>
//#include <queue>
//#include <cstring>
//
//using namespace std;
//typedef pair<int, int> PII;
//const int N = 1010;
//int a[N][N];
//int dx[] = { 0,0,1,-1 };
//int dy[] = { 1,-1,0,0 };
//int n, m;
//
//bool st[N][N];
//// 伤害不超过 mid 的情况下，能够到达第 n ⾏
//bool bfs(int mid)
//{
//	if (n == 1) return true;
//	//找到伤害小于mid return true 
//	memset(st, 0, sizeof st);
//	queue<PII> q;
//	// 1. 把所有的源点加⼊到队列⾥⾯
//	for (int j = 1; j <= m; j++)
//	{
//		q.push({ 1, j });
//		st[1][j] = true;
//	}
//	while (q.size())
//	{
//		auto t = q.front(); q.pop();
//		int i = t.first, j = t.second;
//		for (int k = 0; k < 4; k++)
//		{
//			int x = i + dx[k], y = j + dy[k];
//			if (x >= 1 && x <= n && y >= 1 && y <= m && a[x][y] <= mid && !st[x][y])
//			{
//				q.push({ x,y });
//				st[x][y] = true;
//				if (x == n) return true;
//			}
//		}
//	}
//	return false;
//}
//int main()
//{
//	cin >> n >> m;
//	int left = 0, right = 0;
//	for (int i = 1; i <= n; i++)
//	{
//		for (int j = 1; j <= m; j++)
//		{
//			cin >> a[i][j];
//			right = max(right, a[i][j]);
//		}
//	}
//
//
//	while (left < right)
//	{
//		int mid = left + (right - left) / 2;
//		//伤害最大值为mid,路线找的到伤害小于mid的路线
//		if (bfs(mid)) right = mid;
//		else left = mid + 1;
//
//	}
//	cout << left << endl;
//	return 0;
//}
//
//



#include <iostream>
#include <queue>
#include <cstring>

using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int a[N][N];
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
int n, m;

bool st[N][N];

bool bfs(int mid)
{
	if (n == 1) return true;
	memset(st, 0, sizeof st);
	queue<PII> q;
	for (int j = 1; j <= m; j++)
	{
		q.push({ 1,j });
		st[1][j] = true;
	}
	while (q.size())
	{
		auto t = q.front(); q.pop();
		int i = t.first, j = t.second;
		for (int k = 0; k < 4; k++)
		{
			int x = i + dx[k], y = j + dy[k];
			if (x > n || x < 1 || y > m || y < 1 || st[x][y] || a[x][y] > mid) continue;
			st[x][y] = true;
			q.push({ x,y });
			if (x == n) return true;
		}
	}
	return false;
}
int main()
{
	int l = 0, r = 0;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			cin >> a[i][j];
			r = max(r, a[i][j]);
		}
	}

	while (l < r)
	{
		int mid = l + (r - l) / 2;
		if (bfs(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << l << endl;
	return 0;
}

